Thread: char[] vs char*

  1. #1
    Registered User
    Join Date
    Mar 2016
    Posts
    110

    char[] vs char*

    char*s ="Hello world";
    will place "Hello world" in the read-only parts of the memory, and making s a pointer to that makes any writing operation on this memory illegal.

    char s[]="Hello world";
    puts the literal string in read-only memory and copies the string to newly allocated memory on the stack. Thus making:

    s[0]='J';


    Legal.

    My question is then why does Case 1 below result in Hello World! and Case 2 result in Iello World! ?

    Case 1:


    Code:
    void getToken(char **infix) {
        (*infix)++;
    }
    
    
    int main () {
        char *myString = "Hello World!";
        getToken(&myString);
        printf("%s", myString);
        return 0;
    }

    Case 2:

    Code:
    void getToken(char **infix) {
    (*infix)++;
    }
    
    
    int main () {
        char myString[] = "Hello World!";
        getToken(&myString);
        printf("%s", myString);
        return 0;
    }
    Last edited by Vespasian_2; 05-08-2017 at 12:04 PM.

  2. #2
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,127
    You cannot have compiled either of these two programs.

    1) You do not #include stdio.h in order to use printf()

    2) getToken() does not "Get" anything! Use better names for your functions.

    3) In case 1, infix is a pointer to a pointer to a constant string. In the statement,
    Code:
    (*infix)++;
    You are dereferencing infix one level to a pointer to the char 'H', then incrementing the POINTER, NOT the char itself, so the output is:
    [CODE]ello World![CODE]

    4) Change the printf() statements to add a newline:
    Code:
    printf("%s\n", myString);
    5) As for case 2, it won't even compile as is.

    6) Almost forgot, Please turn on and turn up the warning level to the highest level! You will then see the errors, and warnings you should have seen!!!

    Please make an attempt to correct your code, then repost. Also please choose an indent style and stick to it!
    Last edited by rstanley; 05-08-2017 at 02:01 PM.

  3. #3
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by Vespasian_2 View Post
    will place "Hello world" in the read-only parts of the memory, and making s a pointer to that makes any writing operation on this memory illegal.
    It doesn't necessarily place it in a read-only memory segment (it isn't required to do so). You're just not supposed to write to it. On some systems, you will in fact be able to write to it, but you can't rely on that behavior in portable code. Techincally, you should make your pointer a const char *.

    The first case doesn't result in "Hello ...", but "ello...", as expected (since you incremented the pointer to point to the next character).

    The second version is passing an incompatible pointer type (expected char**, but was passed char (*)[13]), so it's essentially undefined behavior, which means that no explanation is necessary ("anything can happen").

    However, what's actually happening is based on the fact that myString and &myString yield the same address in the case where myString is an array. So you're passing a pointer to the first character (same as if you passed myString), and you increment the element being referred to, giving the observed behavior.

    Again, however, you should be compiling with full warnings and fixing all warnings before running the code.

  4. #4
    Registered User
    Join Date
    Mar 2016
    Posts
    110
    Quote Originally Posted by algorism View Post
    It doesn't necessarily place it in a read-only memory segment (it isn't required to do so). You're just not supposed to write to it. On some systems, you will in fact be able to write to it, but you can't rely on that behavior in portable code. Techincally, you should make your pointer a const char *.

    The first case doesn't result in "Hello ...", but "ello...", as expected (since you incremented the pointer to point to the next character).

    The second version is passing an incompatible pointer type (expected char**, but was passed char (*)[13]), so it's essentially undefined behavior, which means that no explanation is necessary ("anything can happen").

    However, what's actually happening is based on the fact that myString and &myString yield the same address in the case where myString is an array. So you're passing a pointer to the first character (same as if you passed myString), and you increment the element being referred to, giving the observed behavior.

    Again, however, you should be compiling with full warnings and fixing all warnings before running the code.
    I've made a Case 3 where now the argument of movePointer matches the argument of the caller. Yes, I am getting a warning "passing argument 1 of 'movePointer' from incompatible pointer type". But why is this still undefined behaviour if I have matched arguments? Code is cleansed according to Stanleys input:


    Code:
    #include <stdio.h>
    
    void movePointer(char *infix[13]) {
        (*infix)++;
    }
    
    int main () {
        char myString[] = "Hello World!";
        movePointer(myString);
        printf("%s\n", myString);
        return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 09-25-2014, 06:12 AM
  2. Replies: 2
    Last Post: 09-25-2014, 04:03 AM
  3. Replies: 4
    Last Post: 07-24-2012, 10:41 AM
  4. undefined reference to `RunSwmmDll(char*, char*, char*)'
    By amkabaasha in forum C++ Programming
    Replies: 1
    Last Post: 10-31-2011, 12:33 PM
  5. Assigning Const Char*s, Char*s, and Char[]s to wach other
    By Inquirer in forum Linux Programming
    Replies: 1
    Last Post: 04-29-2003, 10:52 PM

Tags for this Thread